package cn.tedu.justone.pack02;

import java.util.concurrent.locks.LockSupport;

/**
 * ZZ：JustOne
 * VX：Andylau2020smile
 * DY：JustOne2018
 * ZT：《》
 */
public class Demo20_方法示例_LockSupport暂停和恢复 {
    //LockSupport暂停和恢复
    //LockSupport暂停和恢复
    //LockSupport暂停和恢复
    // 1,LockSupport.park();让执行它的线程暂停
    //   LockSupport.unpark(t1);让t1线程恢复运行
    //   如果先执行了unpark(t1)方法，则park()没有暂停的效果。
    // 2,LockSupport.parkUntil(long ms);当时间戳到达ms时才会执行。
    //   一般用法是用 (当前时间戳+ 你想延迟的时间) 作为参数传进去。

    //park()、sleep、wait()三者比较
    // 1,所属类不同park(),parkUntil()属于LockSupport类，
    //   sleep是Thread类的方法，
    //   wait()是Object类的方法
    // 2,sleep方法必须try catch捕获异常,parkUnitil不需要捕获异常
    // 3,unpark可以指定唤醒某个阻塞的线程，操作更加精准，
    //   notify（随机唤醒）和notifyAll（全部唤醒）这种操作有的场景可能不适合。
    // 4,park，sleep可以在任何地方使用，wait只能在同步代码块中使用
    // 5,sleep只能自己唤醒，park和wait要等待其它线程唤醒

    public static void main(String[] args) throws InterruptedException {
        foo01();
        foo02();
    }

    //示例一：park() 和 unpark(t1)
    //  线程t1启动后，就用LockSupport.park();让其暂停
    //  2秒后用LockSupport.unpark(t1);让其恢复运行
    public static void foo01() throws InterruptedException {
        Runnable r1 = ()->{
            LockSupport.park();//暂停运行
            System.out.println("hello");
        };

        Thread t1 = new Thread(r1);
        t1.start();

        Thread.sleep(2000);
        LockSupport.unpark(t1);//恢复运行
    }

    //示例二：LockSupport.parkUntil(long ms);
    // 1,本方法不需要人唤醒，时间到自动唤醒
    // 2,传入的参数是当前时间戳加上你想延迟的毫秒数，如果只传毫秒数则无延迟效果。
    public static void foo02(){
        Runnable r1 = ()->{
            long ms = System.currentTimeMillis();
            LockSupport.parkUntil(ms+3000);
            System.out.println("world");
        };

        Thread t1 = new Thread(r1);
        t1.start();

    }
}
